package com.guigu.mq.service.impl;

import cn.hutool.core.util.IdUtil;
import com.guigu.mq.callback.ConfirmCallback;
import com.guigu.mq.callback.ReturnCallback;
import com.guigu.mq.service.PayService;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName:PayServiceImpl
 * @Description://TODO
 * @Author:taoLong
 * @Date:2021/11/17:9:27 星期三
 * @email:2391611102@qq.com or 2391611102qq@gmail.com
 */
@Service
public class PayServiceImpl implements PayService {

    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private ConfirmCallback confirmCallback;
    @Autowired
    private ReturnCallback returnCallback;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 当下单完成后,便会发送这样一个消息给mq来处理,如果超过了30分钟不处理,那么死信队列来给订单设置为取消 支付
     *
     * @param exchangeName
     * @param routeKey
     * @param message
     */
    @Override
    public void sendPayMessage(String exchangeName, String routeKey, String message) {

        /**设置一个全局id放入redis中,防止MQ重复消费,我们在这里放的时订单Id,也可以保证唯一
         * 在redis中设置为30分钟
         */
        redisTemplate.opsForValue().setIfAbsent(message, "mq", 4, TimeUnit.MINUTES);
        /**
         * 在rabbit中设置进全局唯一Id
         */
        rabbitTemplate.convertAndSend(exchangeName, routeKey, message, m -> {
            m.getMessageProperties().setMessageId(message);
            return m;
        });
    }

    /**
     * 确认机制,发送到消费端自动确认
     */
    @PostConstruct
    public void init() {
        rabbitTemplate.setConfirmCallback(confirmCallback);
        /**
         * true:交换机无法进行路由时,将该消息返回给生产者
         * false:
         * 如果发现消息是无法进行路由的,则直接丢弃
         */
        rabbitTemplate.setMandatory(true);
        rabbitTemplate.setReturnCallback(returnCallback);
    }
}
